Lesson 10: Printer Friendly

Managing Namespaces

Printing This Lesson

Select what you’d like to include when you print, and then click the Print Lesson button:

Saving This Lesson

For instructions on saving this lesson (shown below), please select the browser you're using.

chrome icon
Chrome
Firefox icon
Firefox
Internet Explorer 10 icon
IE 11
Safari icon
Safari

Lesson 10 - Managing Namespaces - Chapter 1

Introduction

Hello, and welcome back! In today's lesson, you see how XML uses namespaces to prevent confusion when merging XML documents together into a single document.

Namespaces ensure that CSS, XSL, XSD, and other XML-related files avoid name collisions. What's that? It's when two completely different elements share the same tag name. It's like the first day of school and the teacher says: "Okay, we have three Justins in this class. How should we deal with this?"

Collisions can cause serious misunderstandings. If you stand by the side of the road in America and stick your thumb out, somebody might stop and give you a ride. Do that in Italy, and you could get punched. Same gesture, completely different meanings.

Of course, some words we simply can't misunderstand. XML tags like michelleobama, rockettes, or hopediamond, are so specific and so unambiguous that they just can't collide. They only refer to one thing.

But many words do have multiple meanings. Consider the tag <title>. In the cookbook program, it means one thing, but the same tag would mean something else in British high society or in a real estate office. You can see the problem: There must be a way to specify what kind of <title> we mean.

Element tag name collisions are likely to occur when two companies try to communicate, or merge, their XML data structures.

Ready? Let's get started!

Chapter 2

Using Namespaces

XML uses namespaces to distinguish one group of tag names from another. Our recipes.xml tag names are <cookbook>, <recipe>, <title>, and <instructions>. But what if a publisher asks you to send your cookbook XML file for inclusion in a new book that combines several cookbooks. It's more than likely that merging recipes.xml with the other cookbook's XML would result in name collisions.

How does this happen? Most people choose descriptive tag names. After all, that's one of the great advantages of XML! So in pretty much any XML document that holds recipes, you'll find at least some of these tag names: recipe, instructions, ingredients, and directions.

But they might not have identical meanings in different XML files. Think for a minute about the tag instructions. In our cookbook program, we use it to mean the entire recipe—the ingredients and also the directions about how to use those ingredients, all packed into our single instructions element.

Somebody else's XML cookbook might store the ingredients in a separate element, using three elements (title, ingredients, and instructions) where we've used only the two. When the publisher tries to combine our XML data with this other cookbook's XML, they'll have a name collision problem.


Perhaps you've noticed an ns here and there in the declaration code at the top of XML files?

<svg version="1.0" xmlns="http://www.w3.org/2000/svg">

The ns stands for . . . you guessed it, namespace. These lines of code are specifying unique namespaces. Web page addresses like these are unique, so they're a great way to ensure that two namespaces can't be duplicates. Web page addresses are unique for the same reason that your home address is unique. Nobody else lives in the same state, town, street with the same address number.

Here's another namespace example:

xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"

This code creates a namespace prefix  xmlns:inkscape= that you can then use as a shortcut. From now on, in this file's code, the word inkscape will identify this namespace with this unique Web address http://www.inkscape.org/namespaces/inkscape.  Using this inkscape prefix, you ensure that it's clear what each tag means.

Here's how it works:

In an SVG document, you would use the namespace prefix followed by a colon. This declares that each of these code lines are Inkscape-specific (they exist within this specific namespace). In this way, there's no doubt that the terms pageshadow and zoom  are from the Inkscape set of commands (from the Inkscape namespace):


      inkscape:pageshadow="2"

      inkscape:zoom="0.7"

Let's look at another example, this time from an XSL file.

Here the namespace prefix is called xsl. Then the rest of the XSL document uses that prefix to exclusively identify that its output and template elements are part of this xsl namespace:

Understanding URIs

A URI (Uniform Resource Identifier) is a unique Web address you provide when specifying a namespace. Here's a typical URI:

 "http://www.w3.org/2000/svg"

Some URIs aren't Web addresses, but most are. When they are a Web address, URIs are also called URLs (Uniform Resource Locator). You can put the URI in the root element of an XML document (like the xmlns:xsl example above).

When you put the namespace up top in the root element of a document, it becomes the default namespace for the entire document. It's automatically the namespace of all the rest of the elements in the document. The only exception is any elements that specify their own, different URI in an attribute. Here's how to do this—this code uses a URI as an attribute of an individual element:


<myelement xmlns="http://www.MyWebPage/MyNamespace/">

</myelement>

The great thing about using a default namespace in an ordinary XML document is that you eliminate the need to use prefixes. But some documents use multiple namespaces, like this:


<myrootelement 

xmlns:ohio="http://www.MyWebPage/MyOhioNamespace/"

xmlns:utah="http://www.MyWebPage/MyUtahNamespace/">

So in that case, you do have to use prefixes.

All right, let's take a look at mixing namespaces.

Mixing Namespaces

If you need to get really specific, you can sprinkle namespaces all over the place—even using different namespaces for individual lines of code! Look at this XSL code, and notice how the namespace prefixes identify which code lines are XSL and which are not:


<?xml version="1.0" encoding="UTF-8"?>

><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:for-each select="cookbook/recipe">

     <tr>

       <td bgcolor="lightyellow" width="30%">

<xsl:value-of select="title"/>

</td>

       <td>

<xsl:value-of select="instructions"/>

</td>

     </tr>

</xsl:for-each>

The lines of code with xsl: prefixes are XSL, and the unprefixed <tr> and <td> lines are ordinary HTML. In this way, you can mix and match code lines. Some can have one namespace, others can have a different namespace, and yet others can have no namespace at all. You may never need to use this complex technique—but at least you now know it's available.



XML Challenge!!


Can you think of a situation where you don't need to use namespaces when working with XML?








Chapter 3

Using Namespaces in VB

Name collisions aren't limited to XML. They also crop up in various other areas of computing. But namespaces serve a slightly different purpose in programming languages than they do in XML.

The reason is this: Everybody makes up his or her own names for XML tags. But the names of commands in programming languages are made up by the company that created the language—Microsoft in the case of VB. As a result, Microsoft also gets to define the VB namespaces.

So with computer programming languages, namespaces primarily perform the clerical task of organizing the many thousands of commands into separate code libraries (each library is a separate namespace).

What's more, each of these namespaces can in turn contain other namespaces. It's like subcategories in a real-world library . . .

Show all files

Bringing this idea back to VB . . . take a look at this VB namespace:

System.XML.XPath.

Notice that there are actually three namespaces: System is the primary namespace, but it contains the XML namespace. And XPath is one of the namespaces contained within the XML library. You separate each nested VB namespace with a period.

There are many libraries available to VB—Design, XML, Schema, Web, and dozens of others. VS gives you a choice of various templates when you start a new program. For the cookbook, we chose the Windows Forms Application template. This is the traditional Windows desktop-style application (as opposed to, for example, the new Windows 8 app-type program, or a program designed to run on the Internet).

When we chose the Windows Forms option, VS automatically made available what it considered the necessary code libraries for this kind of application.

Let's take a little tour way down into VB's secret, hidden libraries and see what's there.

  1. Click the Show All Files icon at the top of the Solution Explorer window:
    Show all files
    Show all files
  2. Now click the small arrow next to References in the Solution Explorer.
    References
    References

    A list of default namespaces is revealed. Notice that two of the nine default libraries are dedicated to XML. This reflects the importance of XML in today's computing. But even though XML is a default library, you must still use the Imports command to avoid having to use prefixes in your code.

    The term XML in this code is a namespace prefix:


Dim TheCollectionOfTitles As Xml.XmlNodeList
  1. Right-click System.Windows.Forms in the Solution Explorer. Here you can see VB's complete hidden library, all its namespaces, individual components, and descriptions of what each does.
  2. In the context menu, click View in Object Browser. A window opens on one of VB's vast libraries, the Forms namespace.

If this were a movie, I'd play some triumphant organ music as you gaze in wonder upon this massive underground storehouse.


Included in the Forms library are all things related to, of course, forms: controls such as the TextBox, and its events like Click or Hide, all its properties like its FontName, and so on. Let's look at some of the descriptions.

  1. Click the arrow next to System.Windows.Forms in the Object Browser to display various additional namespaces.
  2. Click the arrow next to System.Windows.Forms in the sublibrary, like this:
Libraries within libraries
Libraries within libraries
  1. Scroll down until you find the TextBox control.

  2. Click the arrow next to TextBox, and then click the arrow next to Base Types to reveal the TextBoxBase list.

  3. Click TextBoxBase, and you'll see all the members (events, properties, and methods) of the TextBox control:
TextBox members
TextBox members

A lightning bolt icon  represents events, a wrench  symbolizes properties, and a box stands for methods.

Tip

What Are Members?

In computer programming, we manipulate objects and make use of their features. Objects are everywhere. A button control is one kind of object. But a list of hotels could be an object. You can even create your own objects.

Objects can have three primary features:

  • Events: These are things that can happen to an object while a program runs, such as being clicked or typed into. In our cookbook, events are subs. Most of the code you write in a VB project describes what the program should do when one of the events is triggered by the user.
  • Properties: These are an object's qualities, such as its size, borderstyle, and color properties.
  • Methods: These are actions the object can perform, like a TextBox's cut, copy, and paste methods.

Many commands (like End or Save) and controls (such as the Textbox) are in the default VB libraries, so they're built into VB. When an object or control is built in, there are a few things you don't need to worry about:

  • Using the Imports command (with a few exceptions, like the XML namespace)
  • Adding a namespace as a prefix in your code
  • Using Project > Add Reference (described below)

If the library containing the TextBox control weren't available (referenced automatically), you would need to prefix its namespace like this in your code:

Dim txtBox As System.Windows.Forms.TextBox()

But the TextBox is referenced. It's built into the default Windows forms version of VB, so it automatically loads when VB starts. What does this mean for you? You can leave off the namespace prefix, like this:

Dim txtBox As TextBox

If you need something not in the default namespaces, you can use the Imports command to reference an additional namespace, as we did when we used the Schema namespace in a previous lesson for example.

But there's yet another category: namespaces that the Imports command cannot see!

A namespace like System.Web.Services (used to create code for Web pages) requires that you "reference" it via the Project menu. Why? Because the cookbook program is based on the Windows Forms Application template—it's a traditional desktop application. So it's highly unlikely you're going to want to use a library full of Internet-specific commands. But if for some reason you do, you must add a reference to the Web.Services namespace. The Imports command won't be able to find this library until you first add a reference to it.

In ordinary programming, you may never need to add a reference to a library. The built-in libraries will contain all the commands you need. But if you're going to do some very advanced math, for example, you'll need to add a reference to the Math library.

Let's take a look. Choose Project > Add Reference. You'll see the few namespaces (also known as assemblies or libraries) that are included in VB by default (the checked ones), and you'll see others you can add by clicking (selecting) them. You'll also find a massive set of libraries in the COM list (you can click it on the left side of the Reference Manager dialog box).

Referenced libraries
Referenced libraries

Recall that you've used the Imports command in the cookbook code. When writing code that manages schemas, for example, you put this line at the top of the Code window: Imports System.Xml.Schema. Essentially, you're referring to a library of commands called Xml.Schema. You're specifying that namespace.

But it's important to realize that the Imports command is badly misnamed. It doesn't actually import anything. It doesn't add a library of commands to the default VB libraries. In fact, it does only one thing: allows you, the programmer, to use a shortcut—you save a little time by not having to provide the full namespace list in your programming code. You can write ValidationEventHandler in your code, rather than having to write System.Xml.Schema.ValidationEventHandler.

Here's some sample code from the Validator program we wrote in a previous lesson:

Excellent suggestions
Excellent suggestions

Okay, let's simplify things a bit. How do you know when you need to import a code library?

There's a sawtooth line under the ValidationEventHandler command, indicating an error.

If you click the red circle with the white x, a drop-down window provides two excellent suggestions about how to fix this problem:

  • Import the System.Xml.Schema namespace.
  • Add the namespace as a prefix to this command, like this: Schema. ValidationEventHandler.

The error in this code is that VB doesn't understand the underlined command. It's not among the built-in VB commands like Dim or End. Programmers don't use the ValidationEventHandler command very often in desktop application programming (except for us XML programmers).

Notice at the top of the figure that I've used a single-quote to temporarily change this line into a comment. With this, VB will ignore the line and won't recognize this namespace.

'Imports System.Xml.Schema

This "commenting out" debugging technique is useful when you want to see what happens if some code is omitted or is replaced by other code.

Later, I'll need to remove that single quote so VB will actually import the Schema namespace. (Or, alternatively—as VB's error message suggests—I can prefix the ValidationEventHandler command with its namespace, Schema. VB's suggestions on how to fix this error are exactly right.)

To sum up, namespaces in VB serve three purposes:

  • Organize language commands. A namespace identifies a code library, much the same way that a sign saying Travel in a real-world bookstore identifies the books in that section. Language commands are stored in sets of libraries based on what the commands do. One set of VB commands validates XML (the Schema namespace), another manages the UI (Forms), yet another adds specialized math commands (Math), and so on.
  • Prevent ambiguity. You want to prevent ambiguity (name collisions) in programming code when two separate commands share the same name.
  • Simplify code. When a programmer uses the Imports command to reference a code library (like Imports System.Xml.Schema), the programmer can then use the libraries' commands in his or her code without having to prepend the namespace. For example, the programmer can just write ValidationEventHandler instead of System.Xml.Schema.ValidationEventHandler.

Chapter 4

Letting the User Edit Recipes

Throughout this course, we've added features to the cookbook program—making it easy for the user to search, select, import, and delete recipes. But there's one more major feature we need to provide: editing.

Cooks will often create a dish and then decide that they could improve it—add more onions or whatever. So they want to change the recipe. There's a hard way to do that:

  1. Copy the recipe into a text editor like Notepad.
  2. Delete the existing version in the cookbook program.
  3. Make the changes.
  4. Select and copy the new, edited Notepad version.
  5. Click the Import button in the cookbook program.

But there's a better solution: Let them make changes directly in the cookbook program.

There's no need for some external text editor. The VB TextBox itself is a text editor. Not only does it display text, the user can change that text. But we programmers do have to write some code to tell the computer what to do when the user changes a recipe's instructions. Our program must update the XML file with the new, modified version of the recipe.

This sounds like an easy programming task. But it turned out to have a few complications I didn't expect. Programmers call complications bugs.

You'll find it helpful to follow the steps I took to get this recipe modification feature working. For one thing, you'll see a programmer in action—the fits and starts, blind alleys, and near misses. And perhaps after seeing me stumble around, you'll be more patient with yourself when your own programming doesn't go smoothly from idea to finished code. Patience and creative thinking are the keys to fixing difficult bugs!

Okay, we're ready to do some XML programming.

We're faced with a classic computer problem in this chapter: When to update the data file?

One solution that even experts recommend surprisingly often is to create a global variable (one that's readable by all events). Let's name it IsDirty. When the user types something into, or clicks, the txtInstructions textbox, you change IsDirty to True. This signals other parts of the program that the user has modified the text and that it's unsaved—so the program needs to update the file:


Private Sub txtInstructions_Click(sender As Object, e As EventArgs) Handles txtInstructions.Click

        IsDirty = True

How do we know when the user is finished editing? When they leave the textbox by clicking another control, like one of the buttons, to do something else. So first thing in every other control's Click event, you would check to see if the IsDirty variable is set to True. If it is, you would then update the recipes.xml file. After you finish updating, you reset the isDirty variable to False, like this:

But there's a problem with this approach. It's untidy, redundant, complicated, and most of all . . . it stinks.

Tip

Making the User Do It

You might be wondering if we can just put another button on the form labeled, "Update the Recipe File." This way, users have to take responsibility for saving a recipe they changed. Isn't this what happens in other software like drawing programs and word processors?

Good points, but our program isn't exactly like a word processor where you're constantly creating new text or editing. The cookbook is mostly for searching and displaying recipes. Modifying them is likely to be relatively uncommon.

But the main reason to have the program update the data rather than the user is that it's the more elegant approach. After all, the user might forget to click that update button. If they only modified one recipe, they'd be annoyed if it didn't save. But what if they typed in dozens of recipes and lost all that data? They'd probably be distraught!

So let's try to find a way to update the data file automatically.

Choosing an Event

In this course, you've learned that you can put VB programming inside events (subs), because VB usually executes a block of code in response to something the user does: KeyPress, Click, TextChanged, and dozens of other events.

So our first step is to figure out in which event to put the code that updates the recipes.xml file. Remember, we're trying to avoid putting it in every event like the previous example that uses an IsDirty variable. Can we find just one event that always triggers when the user finishes modifying a recipe?

We should probably use a textbox event. Just a simple event that happens to the textbox itself.

Okay, watch this series of screen recordings as I try to figure this out. And if you have any questions as you watch, just press Pause and head over to the Discussion Area.


Chapter 4, Video 1: "Part I: Tracking Down and Fixing a Tough Bug", TRANSCRIPT

The three videos in this lesson illustrate what happens when a programmer, me in this case, struggles to solve a difficult problem. Namely, a tough bug. Fortunately, they're not that common. Most of them don't take this long to solve, but I want you to get a feel for what it takes to hack away and track down a bad problem. And let me remind you, you don't need to understand fully all this code, and you certainly aren't expected to memorize it at this point in your career. You merely need to watch as I wrestle this thing.

We want to figure out how to update a recipe. The user is allowed to make changes to any instructions in any recipe that they want to. The question is: when do we update the file on the hard drive in our programming? What event should save this recipe change? It seemed pretty clear that the textbox itself that contains the changed instructions should have an event that does the updating, but which event?

So let's choose the textbox here in this drop-down list, and then over here we'll show all the events that are available to a textbox. And at first I thought maybe the best thing to do would be to put our updating code in the TextChanged event. TextChanged looks promising. It triggers whenever the text is changed, and so I thought, "Well, that makes sense."

But then I realized that pretty much everything that happens in the Cookbook program triggers this event over and over again. If you click the Delete key, or you Show All the Titles, or you Import a recipe—any of those buttons will change the displayed instructions and thus trigger this TextChanged event. Even though the user hasn't modified the recipe, the Delete button, for example, changes this instruction—the instructions shown. The program is constantly overwriting the recipes.xml file if you put in some code here in this TextChanged event to save to the file.

How did I find that out? Well, I tried putting a message box inside here to see what would happen. Then I ran the program and did various things, and I realized that this message box was popping up constantly for almost anything that happened in the program. And even worse, the TextChanged responds hysterically while the user is modifying a recipe, triggering for every key the user presses.

So, what if he or she typed in a 150-word-long paragraph? The hard drive would be grinding away, updating the recipes.xml file on the hard drive over and over again for every key pressed. Now, that won't turn the computer into a space heater, but the words "hyper" and "impractical" do come to mind. So let's go back up to the top and pick a different event, one that might not be quite so hyper.

How about the KeyPress event? That sounds promising. At least this will trigger only when the user is typing. It won't be triggered by other events in the program, like clicking the Delete button. Only by key presses. And although it sounds reasonable to use this, by using the message box again, I found out that, yep, KeyPress, too, triggers every single time a user presses a key.

Realizing then that this really wasn't as trivial a problem as I had first thought, I relaxed a little and I slowed down enough to ask myself the right questions. And if you'll click on the next video, I'll show you the questions that I asked

END TRANSCRIPT



Chapter 4, Video 2: "Part II: Tracking Down and Fixing a Tough Bug", TRANSCRIPT

So let's back up a little bit the way I did and stop for a minute and just ask ourselves: what exactly do we want to do? When do we want to save this recipe that the users edited? And the answer is we want to save it exactly the moment that the user finishes editing that recipe.

Now, how do I know in the programming when the user has finished editing? And the answer to that is it's when the user leaves this text instruction textbox. When he or she starts doing something other than typing instructions in this textbox. When they click a button, or they start a search, or they even shut down the program—any of those things are not typing in this textbox. So I want to find out when the user leaves this box. And the answer comes to me, finally, if I look over here in the possible events for a textbox. There's lots of events, but there is one here that says Leave, so let's give that a try.

There is a Leave event. "Perfect," I thought. "This is it." This makes Visual Basic do all the heavy lifting. It has to watch what the user is doing, and then trigger this Leave event when the user moves on to some other task. No need for me to write code that checks global variables at the start of all my subroutines, and no need to repeatedly update the XML file on the hard drive every time the user simply presses one key. This finally seemed like the clean solution, and here's the code that I put into the Leave event to do the updating.

I thought I was home free. Finally, this is going to work. But, no. I was so happy to find this Leave event that I started just to relax and think about lunch. But bugs can pop up when you least expect them. I started modifying a few recipes to make sure everything was working right and to test this code, and then the bug showed itself. It was a minor bug in the sense that its effects were not catastrophic for the user. The program didn't crash and there was no damage to the data itself, but it took a long time for me to track this down and fix it.

This brings up the question, should you spend hours fixing a minor bug? Well, it's always up to you. If the program is just for your own use and the bug's fairly insignificant, maybe you can just tolerate it, work around it, deal with it, put up with it. But you probably want to polish programs if you're going to share them with others, and you certainly have to polish them, get rid of bugs, when you write professional code.

This Leave event does everything right except one thing. If you finish modifying a recipe and then decide to go and look at a different recipe, there's a bug. You would click the new recipe's title in the list box, and, unfortunately, when you do that after editing in the textbox, when you make the click to go to look at another title, nothing happens. Normally, the minute you click a recipe's title in that list box, that title's instructions show up in the text instructions textbox so you see the whole recipe. But the Leave event prevents this from happening, and I couldn't figure out why.

When you click to see a title, all you see is the instructions for the recipe you just modified, not the instructions for the new recipe you just clicked. This is a discontinuity. The title now selected, that's highlighted in that list box, doesn't match the instructions displayed over here in our textbox. Users would become confused or annoyed, but we really can't blame this problem on the Leave event itself. And so I spent hours trying the different things to discover what this problem was, why the list box wasn't being updated. I'll tell you the solution in the next video

END TRANSCRIPT



Chapter 4, Video 3: "Part III: Tracking Down and Fixing a Tough Bug", TRANSCRIPT

Let me show you how the bug looks. When I press F5 to run the program, I'll go over here, and I'll delete something from the Beef Tips recipe. Now, when I click the Coleslaw recipe, it should show up, but it doesn't. We're still seeing the Beef recipe over here, and that's our bug.

So I did some debugging and single-stepping to see if I could figure out what was happening, and it turned out that the program wasn't updating the list box's selected item property. And this is VB's fault. It seems that in this rare situation, when the user clicks a title in the list box, the list box doesn't get the message. It doesn't know that the user has clicked.

So let's go up here to the list box Click event and see if we can figure out what's going on. One good debugging technique is to simply temporarily insert a message box, and then when you run the program, you can see the contents of a variable. And in this case, we'll see what's the selected item when we run it. And although this is a debugging technique, for some reason this solved the problem. The bug went away. Was I surprised. So I went to lunch. I needed a break.

How does simply pausing this program's execution to display this message box update the selected item property? Why? This is one reason that people often describe programming as half science and half art. The art part includes lurching around and hacking, like I'm doing, until you finally discover its weird solution to an equally weird problem.

But clearly this isn't a real solution because we can't leave a message box debugging technique in the middle of the code. When the user runs it, they won't stand for it. They'd be mystified by a message box constantly appearing. What purpose does it serve? It doesn't for them. It's a debugging technique.

So I thought, "Maybe it's the pause. Maybe it's the fact that VB has to pause here." So I replaced this message box with a pause. The VB Sleep command simply stops execution for whatever amount of time you specify. It works with milliseconds, so 2,000 would be a two second delay. That dead-paused the program, but it didn't solve the bug.

So I then tried a Do events command which, in VB, slows down the program to let other events execute, such as dragging a window while VB is doing something. And this multitasking effect didn't work either. It was just another blind alley.

Then I thought maybe it's not the delay itself, but just the fact that some code, any code, is executing between when the user clicks and the property gets updated. So I tried using the list box's Refresh command. Nothing. Another blind alley. But unbeknownst to me, I was getting closer. You bang on enough doors, one of them probably will open.

Finally, I got the right answer. I tried switching the focus to another object on the form. In this case, I thought I'd try the txtSearch textbox. So I used the Select command to put the focus on the txtSearch. That worked. This was the solution. It won't bother the user. They won't care that the focus has shifted, and it does somehow fix this bug.

Can I explain why this fixes the bug? No. Does it work reliably? Yes. So I don't actually care to know the sordid technical details about what is really not my bug, but Visual Basic's

END TRANSCRIPT

This, finally, seemed the clean solution. In the classroom, I've included the code that I put into the Leave event to do the updating.

Code in the Leave Event


Half science, half art


Let's Chat!

How do you feel about testing and debugging? Do you find it tedious and annoying? Or is it more like a puzzle that's fun to solve? Visit the Discussion Area to discuss with your classmates.